package dd.lo.chapter5;

import javafx.application.Application;
import javafx.application.Platform;
import javafx.concurrent.Task;
import javafx.scene.Scene;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.input.KeyCode;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
import org.opencv.core.*;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;

import java.io.ByteArrayInputStream;
import java.util.Date;

/**
 * 对应练习示例
 * Draw a circle in the matrix using void cv::circle(InputOutputArray img, cv::point center, intradius, cv::Scalar color, int thickness=1, int line_type=8, int shift=0)
 */
public class Example2 extends Application {
    private ImageView imageView;

    public static void main(String[] args) {
        System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
        launch(args);
    }

    @Override
    public void start(Stage stage) throws Exception {
        int w = 100, h = 100;
        imageView = new ImageView();
        imageView.setFitWidth(w);
        imageView.setFitHeight(h);
        //imageView放到一个pane的中间
        BorderPane root = new BorderPane();
        root.setCenter(imageView);
        Scene scene = new Scene(root, w, h);
        scene.setOnKeyReleased(keyEvent -> {
            //按下esc可以关闭程序
            if (KeyCode.ESCAPE == keyEvent.getCode()) {
                stage.close();
            }
        });
        stage.setScene(scene);
        stage.setTitle("C5E2-Drawing");
        stage.setResizable(false);
        asyncDraw(w, h);
        stage.show();
    }

    private void asyncDraw(int w, int h) {
        Task<Void> task = new Task<Void>() {
            @Override
            protected Void call() throws Exception {
                long startTime = new Date().getTime();
                //创建一张图片，8bit，3通道
                Mat bg = new Mat(h, w, CvType.CV_8UC3);
                //如果不进行0填充，则背景是五颜六色的雪花状，setIdentity的作用是对角线设置成Scalar的值，对角线以外的设置成0，此处作用是全部填充为0
//                Core.setIdentity(bg, new Scalar(0.0));
                //或使用最简单的setTo功能，可以将对应的channel设置成需要的值
                bg.setTo(new Scalar(0, 0, 0));
                //画圆的圆心，这里先弄成随机点，颜色是BGR的蓝色
                int rx = (int) (Math.random() * w), ry = (int) (Math.random() * h);
                Imgproc.circle(bg, new Point(rx, ry), 10, new Scalar(new double[]{255, 0, 0}), 2, Imgproc.LINE_8);
                //画矩形，左上角点和宽高
                rx = 20;
                ry = 5;
                int rw = 20;
                int rh = 15;
                Imgproc.rectangle(bg, new Rect(rx, ry, rw, rh), new Scalar(new double[]{0, 255, 0}));
                MatOfByte buffer = new MatOfByte();
                Imgcodecs.imencode(".jpeg", bg, buffer);
                Platform.runLater(() -> imageView.setImage(new Image(new ByteArrayInputStream(buffer.toArray()))));
                System.out.printf("Circle drawing time consume: %d ms.\n", new Date().getTime() - startTime);
                return null;
            }
        };
        new Thread(task).start();
    }
}
